/*****************************************************************
 * Filename   | Example_Programs.cpp
 * Author     | Scott J. Schneider 
 *
 * Assignment | Programming Exercise for ECT362
 * Due date   | 01/01/07
 *****************************************************************/

/*****************************************************************
 * Problem Statement | 
 *
 * Inputs            | 
 * Outputs           | 
 * Processes         | 
 * 
 * Pseudocode Design | 1.
 *                   | 2. 
 *                   | 3. 
 *                   | 4. 
 ******************************************************************/

/* Preprocessor Directives */
#include <windows.h>  // Win32 API
#include "resource.h"  // resources for your application
#include <iostream>  
#include <string.h> 
#include <stdio.h>
#include <fstream>

#define ID_ADDBUTTON	1001 //IDs for components 
#define ID_DELETEBUTTON 1002
#define ID_LIST			1010
#define ID_FNAME		1020
#define ID_LNAME		1021
#define ID_PHN			1022
#define ID_EMAIL		1023
#define COLS 100

 struct ContactInfo { // struct for contacts
	char fnames[100];
	char lnames[100];
	char emails[100];
	char phnums[100];
}contacts[100];

int in_cnt = 0, out_cnt = 0, file_limit; // global variables used for tracking contacts


/* Function Prototypes */
LRESULT CALLBACK WndProc( HWND, UINT, WPARAM, LPARAM );  //the window procedure
/* A callback function is passed (by reference) to another function */

/* Global variables */

/* Functions */
/*****************************************************************
 * Function    | WinMain()
 * Description | Entry point for our application, we create and 
 *             |  register a window class and then call CreateWindow
 * Inputs      | None
 * Output      | Integer value 0
 *****************************************************************/ 
int WINAPI WinMain( HINSTANCE hInstance, 
				    HINSTANCE hPrevInstance,
                    LPSTR szCmdLine, 
					int iCmdShow ) 
{
    static char szAppName[] = "My Window";
	
	HWND        hwnd, lhWnd;
    WNDCLASSEX  wndclass;  // This is our new windows class
	MSG msg;

	/*  Fill in WNDCLASSEX struct members  */
    wndclass.cbSize         = sizeof(wndclass);
    wndclass.style          = CS_HREDRAW | CS_VREDRAW;
    wndclass.lpfnWndProc    = WndProc;
    wndclass.cbClsExtra     = 0;
    wndclass.cbWndExtra     = 0;
    wndclass.hInstance      = hInstance;
    wndclass.hIcon          = LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_MyIcon));
    wndclass.hIconSm        = (HICON)LoadImage(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_MyIcon), IMAGE_ICON, 16, 16, 0);
    wndclass.hCursor        = LoadCursor(NULL, IDC_ARROW);
    wndclass.hbrBackground  = (HBRUSH) GetStockObject(WHITE_BRUSH);
    wndclass.lpszClassName  = szAppName;
    wndclass.lpszMenuName   = NULL;

    /*  Register a new window class with Windows  */
    RegisterClassEx(&wndclass);

    /*  Create a window based on our new class  */
    hwnd = CreateWindow(szAppName,  // class name the window is to be based on 
						"My Contacts",  // the title of the window that will 
						                  //  appear in the bar at the top
						WS_OVERLAPPEDWINDOW,  // window style (a window that 
						                      //  has a caption, a system menu, 
											  //  a thick frame and a minimise 
											  //  and maximise box)
						/* Use default starting location for window */
						CW_USEDEFAULT, // initial x position (top left corner)
						CW_USEDEFAULT, // initial y position (top left corner)
						830, // initial width
						500, // initial height
						NULL, // window parent (NULL for not a child window)
						NULL, // menu (NULL to use class menu)
						hInstance, // the program instance passed to us
						NULL);  // pointer to any parameters wished to be 
	                            //  passed to the window producer when the window
	                            //  is created
 
	if(hwnd == NULL)  // check to see if an error occurred in creating the window
    {
        MessageBox(NULL, "Window Creation Failed!", "Error!",
            MB_ICONEXCLAMATION | MB_OK);
        return 0;
    }

    /* Show and update our window  */
    ShowWindow(hwnd, iCmdShow);
    UpdateWindow(hwnd);

 
	/*  Retrieve and process any queued messages until we get WM_QUIT  */
	/* Recall that Windows uses a messaging system to notify window of */
	/*  user actions												   */
    while ( GetMessage(&msg, NULL, 0, 0) ) 
	{
		TranslateMessage(&msg);  // for certain keyboard messages 
		DispatchMessage(&msg);  // send message to WndProc
    } 

    /*  Exit with status specified in WM_QUIT message  */
    return msg.wParam;
} // end WinMain()


/*****************************************************************
 * Function    | WinProc()
 * Description | Whenever anything happens to your window, Windows 
 *             |  will call this function telling you what has happened. 
 *             |  The message parameter contains the message sent
 * Inputs      | None
 * Output      | Integer value 0
 *****************************************************************/ 
LRESULT CALLBACK WndProc( HWND hwnd, 
						  UINT iMsg, 
						  WPARAM wParam, 
						  LPARAM lParam ) 
{
    PAINTSTRUCT ps;
	HDC hdc;
	static HWND  addbutton, listbox, fname, lname, phn, email, deletebutton; // declares components
	
	int len;
	int i = 0;
	char name[100];
	char nametest[100] = "Type Contact Info here"; 
	char newline[100] = "    ";
	char new_contact;
	char line[COLS];



	/*  Switch according to what type of message we have received  */
    switch ( iMsg ) 
	{
		case WM_PAINT:
		/* We receive WM_PAINT every time window is updated  */
			hdc = BeginPaint(hwnd, &ps);
			//TextOut(hdc, 10, 160, "My First Window", 15);
			EndPaint(hwnd, &ps);
			break;
		case WM_CREATE:
        /* Operations to be performed whenthis window is created */ 
			/* Create a child window for a pushbutton */
			addbutton = CreateWindow(  "BUTTON",  // predefined class 
								"Add Contact",  // button text 
								WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON, 
								// Size and position values are given 
								//  explicitly, because the CW_USEDEFAULT 
								//  constant gives zero values for buttons. 
								690,  // starting x position 
								420,  // starting y position 
								100, // button width 
								30,  // button height 
								hwnd, // parent window 
								(HMENU)ID_ADDBUTTON, // no menu 
								(HINSTANCE) 0,  // ignored for Windows XP
								NULL );  // pointer not needed 
			deletebutton = CreateWindow(  "BUTTON",  // predefined class 
								"Delete Contact",  // button text 
								WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON, 
								// Size and position values are given 
								//  explicitly, because the CW_USEDEFAULT 
								//  constant gives zero values for buttons. 
								690,  // starting x position 
								10,  // starting y position 
								110, // button width 
								30,  // button height 
								hwnd, // parent window 
								(HMENU)ID_DELETEBUTTON, // no menu 
								(HINSTANCE) 0,  // ignored for Windows XP
								NULL );  // pointer not needed 
			
			/* Create a list box to display values within the window */
			listbox = CreateWindow( "LISTBOX",  // predefined class
				  				    "",  // initial lst box text (empty)
									// automatically sort items in list box 
									//  and include a vertical scroll bar 
									//  with a border
								    WS_CHILD | WS_VISIBLE | LBS_NOTIFY | 
									WS_VSCROLL | WS_BORDER,  
									10,  // starting x position
									10,  // starting y position
									550,  // list box width
									300,  // list box height
									hwnd,  // parent window
									(HMENU)ID_LIST,  // no menu
									(HINSTANCE) 0,  // ignored for Windows XP
									NULL ); // pointer not needed
						FILE *file_ptr;
	
				/* Read command line information */
	

				file_ptr = fopen("contacts.txt", "r");  // open the contacts.txt file for 
													   //  reading only
				if( file_ptr == NULL ) // failed to open file
				{
					MessageBox(NULL, "ERROR OPENING FILE","Error Opening Contact File", MB_ICONINFORMATION | MB_OK); 
					exit( 0 );  // exit program
				}

				/* Read file line-by-line, storing each line into a seperate row in */
				/*  the names[][] string array									    */
				while( fgets( line, COLS, file_ptr) != NULL )
				{
					sscanf(line, "%s\t%s\t%s\t%s", contacts[in_cnt].fnames, contacts[in_cnt].lnames, contacts[in_cnt].emails, contacts[in_cnt].phnums);
					char temp[100]; // adds contacts to array before going into the listbox
							strcpy(temp, contacts[in_cnt].fnames);
							strcat(temp, " " );
							strcat(temp, contacts[in_cnt].lnames);
							strcat(temp, " " );
							strcat(temp, contacts[in_cnt].phnums);
							strcat(temp, " " );
							strcat(temp, contacts[in_cnt].emails);
							puts(temp);
					if(temp != newline)
					{
						SendDlgItemMessage( hwnd, ID_LIST, LB_ADDSTRING, 0, LPARAM(temp)); // adds line to listbox
						in_cnt++;  // increment to next row in first and last name arrays 
					}

				}
				file_limit = in_cnt;  // store location of any new data entered from user
				fclose(file_ptr);  //close file since all data has been extracted


			/* Create edit box for adding and deleting items from list */
			fname = CreateWindow( "EDIT",  // predefined class
				                    "First Name",  // initial lst box text (empty)
									// create an edit box with a border
									WS_CHILD | WS_VISIBLE | WS_BORDER, 
									10,  // starting x position
									425,  // starting y position
									160,  // list box width
									20,  // list box height
									hwnd,  // parent window
									(HMENU)ID_FNAME,  // no menu
									(HINSTANCE) 0,  // ignored for Windows XP
									NULL); // pointer not needed
			lname = CreateWindow( "EDIT",  // predefined class
				                    "Last Name",  // initial lst box text (empty)
									// create an edit box with a border
									WS_CHILD | WS_VISIBLE | WS_BORDER, 
									180,  // starting x position
									425,  // starting y position
									160,  // list box width
									20,  // list box height
									hwnd,  // parent window
									(HMENU)ID_LNAME,  // no menu
									(HINSTANCE) 0,  // ignored for Windows XP
									NULL); // pointer not needed
			phn = CreateWindow( "EDIT",  // predefined class
				                    "Phone Number",  // initial lst box text (empty)
									// create an edit box with a border
									WS_CHILD | WS_VISIBLE | WS_BORDER, 
									350,  // starting x position
									425,  // starting y position
									160,  // list box width
									20,  // list box height
									hwnd,  // parent window
									(HMENU)ID_PHN,  // no menu
									(HINSTANCE) 0,  // ignored for Windows XP
									NULL); // pointer not needed
			email = CreateWindow( "EDIT",  // predefined class
				                    "Email",  // initial lst box text (empty)
									// create an edit box with a border
									WS_CHILD | WS_VISIBLE | WS_BORDER, 
									520,  // starting x position
									425,  // starting y position
									160,  // list box width
									20,  // list box height
									hwnd,  // parent window
									(HMENU)ID_EMAIL,  // no menu
									(HINSTANCE) 0,  // ignored for Windows XP
									NULL); // pointer not needed
			break;
		case WM_DESTROY:
			{
		/* Window has been destroyed, so exit cleanly  */
			int saveMessage = MessageBox(NULL, "Would you like to save your changes?", "Save Changes?", MB_ICONQUESTION | MB_YESNO | MB_DEFBUTTON1 | MB_APPLMODAL);

			switch(saveMessage)
			{
			case IDYES:
				{
					std::ofstream ofs("contacts.txt");
					ofs.close();
					file_ptr = fopen("contacts.txt", "w");
					if( file_ptr == NULL ) // failed to open file
					{
						MessageBox(NULL, "Error Opening Contacts File", "Error", MB_ICONINFORMATION | MB_OK);
						exit( 0 );  // exit program
					}
					//fputc('\n', file_ptr);
					/* create new contact line for file */
					for( out_cnt = 0; out_cnt < in_cnt; out_cnt++ ) // constructs line for addition to the txt doc
					{
						strcpy(line, contacts[out_cnt].fnames);
						strcat(line, "\t");
						strcat(line, contacts[out_cnt].lnames);
						strcat(line, "\t");
						strcat(line, contacts[out_cnt].emails);
						strcat(line, "\t");
						strcat(line, contacts[out_cnt].phnums);
						strcat(line, "\n");

						/* Update file with added contacts */
						fputs(line, file_ptr);  // write new contact information to file
					}
					MessageBox(NULL, "Saved", "Saved", MB_ICONINFORMATION | MB_OK | MB_APPLMODAL); //confirms save
					fclose(file_ptr);
					break;
				}
			case IDNO:
				{
					//MessageBox(NULL, "No Changes Saved", "Saved", MB_ICONINFORMATION | MB_OK | MB_APPLMODAL);
					break;
				}
			}

			PostQuitMessage(0);
			break;
			}
		case WM_COMMAND:
 	    /* User selected a command from a menu or a control sent a message */
			if (HIWORD(wParam) == BN_CLICKED) 
            { 
                switch (LOWORD(wParam)) 
                { 
					case ID_ADDBUTTON:
						//MessageBox(NULL, "Add Button Pressed", "ADD",
								  // MB_ICONINFORMATION | MB_OK);
						/* Read length of string entered into the text box */
						len = GetWindowTextLength(fname);  
						/* Read string from edit box and store to name[] */
						GetWindowText(fname, name, len + 1);
						if(len == 0)
						{
							MessageBox(NULL, "No Contact Information", "No Contact", MB_ICONINFORMATION | MB_OK); // tests to see if a contact has been added 
						}
						else
						{
							//need to add new line to struct
							GetWindowText(fname,contacts[in_cnt].fnames, len + 1); // gets length ot contact then adds to struct
							len = GetWindowTextLength(lname);
							GetWindowText(lname, contacts[in_cnt].lnames, len + 1);
							len = GetWindowTextLength(phn);
							GetWindowText(phn, contacts[in_cnt].phnums, len + 1);
							len = GetWindowTextLength(email);
							GetWindowText(email, contacts[in_cnt].emails, len + 1);
		
							char temp[100]; // pulls from struct new contact then formats the info to be added to the list box
							strcpy(temp, contacts[in_cnt].fnames);
							strcat(temp, " " );
							strcat(temp, contacts[in_cnt].lnames);
							strcat(temp, " " );
							strcat(temp, contacts[in_cnt].phnums);
							strcat(temp, " " );
							strcat(temp, contacts[in_cnt].emails);
							puts(temp);
							SendDlgItemMessage( hwnd, ID_LIST, 
							                LB_ADDSTRING, 0, 
											(LPARAM)temp); // adds to listbox
							SetWindowText(fname,""); //clears text fields
							SetWindowText(lname, "");
							SetWindowText(phn, "");
							SetWindowText(email, "");
							in_cnt++;
							MessageBox(NULL, "Contact Added", "Contact Added", MB_ICONINFORMATION | MB_OK); // confirms add
						}
						break; 
					case ID_DELETEBUTTON:
						int row = SendDlgItemMessage(hwnd, ID_LIST, LB_GETCURSEL, 0,0); // gets row id
						if(row <= -1) // allows the delete to function to exit if the user does not select a row
						{
							MessageBox(NULL,"To remove a contact, first click to highlight the desired contact. Then click the delte button",  "How To Remove Contacts", MB_ICONINFORMATION | MB_OK); 
							break;
						}
						SendDlgItemMessage(hwnd, ID_LIST, LB_DELETESTRING, WPARAM(row), 0); //deletes selected row using the row id
						int row_cnt = in_cnt;
						for(int i= 0; i < row_cnt; i++) // removes old contact by overwriting it in the struct
						{
							contacts[row] = contacts[row + 1];

						}
						in_cnt--; // decrements count 
						MessageBox(NULL, "Contact Deleted", "Contact Deleted", MB_ICONINFORMATION | MB_OK); // confirms delete
						break;
				}
			}
			break;
		default:
        /* We do not want to handle this message so pass back to Windows */
        /*  to handle it in a default way                                */
			return DefWindowProc(hwnd, iMsg, wParam, lParam);
	}
	return 0;

} // end WndProc

